package com.ity.teamanagement.service.Impl;

import com.ity.teamanagement.code.CommonCode;
import com.ity.teamanagement.code.UserCode;
import com.ity.teamanagement.entity.Role;
import com.ity.teamanagement.entity.User;
import com.ity.teamanagement.entity.inputParam.AddUserParam;
import com.ity.teamanagement.entity.inputParam.UpdateUserParam;
import com.ity.teamanagement.entity.inputParam.UserLogin;
import com.ity.teamanagement.entity.outputResult.UserDetail;
import com.ity.teamanagement.entity.outputResult.UserDetailTemp;
import com.ity.teamanagement.entity.outputResult.UserDetailVo;
import com.ity.teamanagement.exception.ExceptionUtils;
import com.ity.teamanagement.mapper.UserMapper;
import com.ity.teamanagement.result.Result;
import com.ity.teamanagement.service.UserService;
import com.ity.teamanagement.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author coderFu
 * @create 2021/5/23
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Resource
    private IdWorker idWorker;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private HttpServletRequest request;



    @Override
    public Object queryUserByUserNameAndPwd(UserLogin userLogin, HttpServletResponse response) {
        int count = userMapper.queryUserByName(userLogin.getUsername());
        if (count<1){
            ExceptionUtils.error(UserCode.USER_NOT_EXIST);
        }
        UserDetail userDetail = userMapper.queryUserByUserNameAndPwd(userLogin);
        if (userDetail == null){
            ExceptionUtils.error(UserCode.USER_PASSWORD_ERROR);
        }
        //验证成功 返回用户令牌与用户数据
        String sessionId = passwordEncoder.encode(String.valueOf(idWorker.nextId()));
        String idBase64 = Base64Utils.encodeToString(userDetail.getId().toString());
        sessionId = sessionId+idBase64;
        redisTemplate.opsForValue().set(sessionId,userDetail,7L, TimeUnit.DAYS);
        response.setHeader("Set-Cookie",sessionId);
        UserDetailTemp userDetailTemp = new UserDetailTemp();
//        userDetailTemp = (UserDetailTemp)userDetail;
        userDetailTemp.setToken(sessionId);
        userDetailTemp.setId(userDetail.getId());
        userDetailTemp.setCreateTime(userDetail.getCreateTime());
        userDetailTemp.setPhone(userDetail.getPhone());
        userDetailTemp.setUsername(userDetail.getUsername());
        userDetailTemp.setUserRole(userDetail.getUserRole());
        userDetailTemp.setUpdateTime(userDetail.getUpdateTime());
        return userDetailTemp;
    }

    @Override
    public void logout() {
        String parameter = request.getHeader("Set-Cookie");
        if (parameter != null) {
           redisTemplate.delete(parameter);
        } else {
            ExceptionUtils.error(CommonCode.DATA_ERROR);
        }
    }

    @Override
    public PageableDetails findAllUsers(Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        int total = userMapper.findAllUserTotal();
        if (total == 0){
            return new PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),new ArrayList<>());
        }
        List<UserDetailVo> userDetailList = userMapper.findAllUsers(pageSize*pageNumber,pageSize);
        return new PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),userDetailList);
    }

    @Override
    public void backAddUser(AddUserParam addUserParam) {
        if (addUserParam == null){
            ExceptionUtils.error(UserCode.USER_NOT_EXIST);
        }
        Integer count = userMapper.findUserNameIsExist(addUserParam.getUsername());
        if (count>=1){
            ExceptionUtils.error(UserCode.USER_NAME_IS_EXIST);
        }
        User user = new User();
        user.setUsername(addUserParam.getUsername());
        user.setPassword(addUserParam.getPassword());
        user.setUserRole(addUserParam.getUserRole());
        user.setPhone(addUserParam.getPhone());
        user.setCreateTime(new Date());
        Integer userCount = userMapper.addUser(user);
        if (userCount<1){
            ExceptionUtils.error(UserCode.USER_CREATE_SUCCESS);
        }
    }

    @Override
    public List<Role> findAllRole() {
        return userMapper.findAllRole();
    }

    @Override
    public void backUpdateUser(UpdateUserParam updateUserParam) {
        if(updateUserParam == null){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }
        User user = new User();
        user.setUserRole(updateUserParam.getUserRole());
        user.setPassword(updateUserParam.getPassword());
        user.setPhone(updateUserParam.getPhone());
        user.setId(updateUserParam.getId());
        user.setUpdateTime(new Date());
        Integer count = userMapper.updateUser(user);
        if (count<1){
            ExceptionUtils.error(UserCode.USER_UPDATE_ERROR);
        }
    }

    @Override
    public void backDeleteUserById(List<Long> ids) {
        if(ids.size() == 0){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }
        Integer count = userMapper.deleteUserById(ids);
        if (count<1){
            ExceptionUtils.error(UserCode.USER_DELETE_ERROR);
        }
    }

    @Override
    public UserDetail backFindUserById(Long id) {
        if (id == null){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }
        return userMapper.findUserById(id);
    }


    /**
     * 返回
     *
     * @param pageNumber 当前页
     * @param pageSize   每页条数
     * @param count      总条数
     * @param list       返回数据
     * @param <T>        泛型
     * @return
     */
    public <T> PageableDetails returnPageable(int pageNumber, Integer pageSize, Integer count, List<T> list) {
        return new PageableDetails<>(pageNumber, pageSize, count, list);
    }


    /**
     * 返回总页数
     *
     * @param total
     * @param pageSize
     * @return
     */
    public int returnPages(int total, int pageSize) {
        return PageUtils.returnPages(total, pageSize);
    }
}


